package com.example.batchdemo.service.impl;

import com.example.batchdemo.config.BulkAdjustmentFileHandler;
import com.example.batchdemo.model.BulkAdjUser;
import com.example.batchdemo.model.BulkAdjustment;
import com.example.batchdemo.model.BulkAdjustmentError;
import com.example.batchdemo.service.BulkAdjustmentService;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author jason.tang
 * @Date 2019-10-07 08:54
 * @Desc
 */

@Slf4j
@Service("bulkAdjUserService")
public class BulkAdjUserServiceImpl implements BulkAdjustmentService {

    @Autowired
    private BulkAdjustmentFileHandler bulkAdjustmentFileHandler;

    @Override
    public BulkAdjustment uploadDataFile(byte[] fileBytes, String fileType, String fileName) throws Exception {
        // save file to temp folder
        BulkAdjustment bulkAdjustment = bulkAdjustmentFileHandler.uploadFile(fileBytes, fileName);
        bulkAdjustment.setFileType(fileType);

        // read file
        List<LinkedHashMap<String, String>> dataList = bulkAdjustmentFileHandler.getBulkAdjUserDataFromExcel(bulkAdjustment.getTargetFilePath(), SHEET_NAME_DATA);

        // verify data
        bulkAdjustment = this.verifyData(bulkAdjustment, dataList);

        // add to temp table if no any error.
        bulkAdjustment = this.addBulkAdjDataToTempTbl(bulkAdjustment);

        return bulkAdjustment;
    }

    private BulkAdjustment verifyData(BulkAdjustment bulkAdjustment, List<LinkedHashMap<String, String>> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            log.debug("BulkAdjGrantService.verifyParticipantData -> Incorrect file. File is empty.");
            throw new RuntimeException("BULK_ADJUSTMENT_FILE_IS_EMPTY");
        }
        List<BulkAdjustmentError> errorDataList = new ArrayList<>();
        List<BulkAdjUser> bulkAdjDataList = new ArrayList<>();

        bulkAdjustment.setStatus("PD");

        for (LinkedHashMap<String, String> dataMap : dataList) {
            String errorMsg = "";
            String content = this.getContentAsStr(dataMap);

            String rowNum = dataMap.getOrDefault(COL_NAME_ROW_NUM, "");
            String userNum = dataMap.getOrDefault(COL_NAME_USER_NUM, "");
            String userName = dataMap.getOrDefault(COL_NAME_USER_NAME, "");
            String address = dataMap.getOrDefault(COL_NAME_ADDRESS, "");

            if (StringUtils.isBlank(content)) {
                errorMsg += "Empty row";
            } else {
                if (StringUtils.isBlank(userNum)) {
                    errorMsg += "User Num cannot be empty. ";
                } else if (!StringUtils.isNumeric(userNum)){
                    errorMsg += "Incorrect User Num.";
                }

                if (StringUtils.isBlank(userName)) {
                    errorMsg += "User name cannot be empty. ";
                }

                if (StringUtils.isBlank(address)) {
                    errorMsg += "Address cannot be empty. ";
                }
            }

            log.info("Error Msg: {}", errorMsg);

            if (StringUtils.isNotBlank(errorMsg)) {
                bulkAdjustment.setStatus(BulkAdjustmentService.BULK_ADJ_STATUS_DATA_ERROR);
                BulkAdjustmentError errorData = BulkAdjustmentError.builder().rowNum(Integer.valueOf(rowNum))
                        .content(content).errorMsg(errorMsg).build();

                errorDataList.add(errorData);
            } else {
                BulkAdjUser bulkAdjUser = new BulkAdjUser();

                bulkAdjUser.setAction(BulkAdjustmentService.BULK_ADJ_ACTION_MODIFY);
                bulkAdjUser.setRowNum(Integer.valueOf(rowNum));
                bulkAdjUser.setUserNum(Integer.valueOf(userNum));
                bulkAdjUser.setUsername(userName);
                bulkAdjUser.setAddress(address);

                bulkAdjDataList.add(bulkAdjUser);
            }
        }

        if (BulkAdjustmentService.BULK_ADJ_STATUS_DATA_ERROR.equals(bulkAdjustment.getStatus())) {
            bulkAdjustment.setNumOfRecords(errorDataList.size());
            bulkAdjustment.setErrorDataList(errorDataList);
        } else {
            if (bulkAdjDataList.isEmpty()) {
                throw new RuntimeException("BULK_ADJUSTMENT_FILE_IS_EMPTY");
            }
            bulkAdjustment.setNumOfRecords(bulkAdjDataList.size());
            bulkAdjustment.setBulkAdjUsers(bulkAdjDataList);
        }
        return bulkAdjustment;
    }

    private String getContentAsStr(LinkedHashMap<String, String> dataMap) {
        Joiner joiner = Joiner.on(" | ").skipNulls();
        List<String> list = new ArrayList<String>();
        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
            String value = entry.getValue();
            if (COL_NAME_ROW_NUM.equals(entry.getKey()) || value == null) {
                continue;
            }
            list.add(value);
        }
        return joiner.join(list);
    }

    private BulkAdjustment addBulkAdjDataToTempTbl(BulkAdjustment bulkAdjustment) {
        // 写入到数据库的临时数据表中
        return bulkAdjustment;
    }


    @Override
    public BulkAdjustment submitBulkAdjData(BulkAdjustment bulkAdjustment) {
        // 读取临时表的数据，做相关操作
        return null;
    }


}
